1 using System.Collections.Generic;
2 using
UnityEngine;
3 using
System.Collections;
4 using
Hashtable = ExitGames.Client.Photon.Hashtable;
5
6
7 ///
<summary>Finds out which PickupItems are not spawned at the moment and send this to new players.</summary>
8 ///
<remarks>Attach this component to a single GameObject in the scene, not to all PickupItems.</remarks>
9 [RequireComponent(
typeof(PhotonView))]
10 public
class PickupItemSyncer : Photon.MonoBehaviour
11 {
12     
public bool IsWaitingForPickupInit;
13     
private const float TimeDeltaToIgnore = 0.2f;
14
15
16     
public void OnPhotonPlayerConnected(PhotonPlayer newPlayer)
17     {
18         
if (PhotonNetwork.isMasterClient)
19         {
20             
this.SendPickedUpItems(newPlayer);
21         }
22     }
23     
24     
public void OnJoinedRoom()
25     {
26         Debug.Log(
"Joined Room. isMasterClient: " + PhotonNetwork.isMasterClient + " id: " + PhotonNetwork.player.ID);
27         
// this client joined the room. let's see if there are players and if someone has to inform us about pickups
28         
this.IsWaitingForPickupInit = !PhotonNetwork.isMasterClient;
29
30         
if (PhotonNetwork.playerList.Length >= 2)
31         {
32             
this.Invoke("AskForPickupItemSpawnTimes", 2.0f);
33         }
34     }
35
36
37     
public void AskForPickupItemSpawnTimes()
38     {
39         
if (this.IsWaitingForPickupInit)
40         {
41             
if (PhotonNetwork.playerList.Length < 2)
42             {
43                 Debug.Log(
"Cant ask anyone else for PickupItem spawn times.");
44                 
this.IsWaitingForPickupInit = false;
45                 
return;
46             }
47
48
49             
// find a another player (than the master, who likely is gone) to ask for the PickupItem spawn times
50             PhotonPlayer nextPlayer = PhotonNetwork.masterClient.GetNext();
51             
if (nextPlayer == null || nextPlayer.Equals(PhotonNetwork.player))
52             {
53                 nextPlayer = PhotonNetwork.player.GetNext();
54                 
//Debug.Log("This player is the Master's next. Asking this client's 'next' player: " + ((nextPlayer != null) ? nextPlayer.ToStringFull() : ""));
55             }
56             
57             
if (nextPlayer != null && !nextPlayer.Equals(PhotonNetwork.player))
58             {
59                 
this.photonView.RPC("RequestForPickupTimes", nextPlayer);
60                 
61                 
// you could restart this invoke and try to find another player after 4 seconds. but after a while it doesnt make a difference anymore
62                 
//this.Invoke("AskForPickupItemSpawnTimes", 2.0f);
63             }
64             
else
65             {
66                 Debug.Log(
"No player left to ask");
67                 
this.IsWaitingForPickupInit = false;
68             }
69         }
70     }
71
72     
[RPC]
73     
public void RequestForPickupTimes(PhotonMessageInfo msgInfo)
74     {
75         
if (msgInfo.sender == null)
76         {
77             Debug.LogError(
"Unknown player asked for PickupItems");
78             
return;
79         }
80
81         SendPickedUpItems(msgInfo.sender);
82     }

83
84
85     ///
<summary>Summarizes all PickupItem ids and spawn times for new players. Calls RPC "PickupItemInit".</summary>
86     ///
<param name="targtePlayer">The player to send the pickup times to. It's a targetted RPC.</param>
87     
private void SendPickedUpItems(PhotonPlayer targtePlayer)
88     {
89         
if (targtePlayer == null)
90         {
91             Debug.LogWarning(
"Cant send PickupItem spawn times to unknown targetPlayer.");
92             
return;
93         }
94
95         
double now = PhotonNetwork.time;
96         
double soon = now + TimeDeltaToIgnore;
97
98
99         PickupItem[] items =
new PickupItem[PickupItem.DisabledPickupItems.Count];
100         PickupItem.DisabledPickupItems.CopyTo(items);
101
102         List<
float> valuesToSend = new List<float>(items.Length * 2);
103         
for (int i = 0; i < items.Length; i++)
104         {
105             PickupItem pi = items[i];
106             
if (pi.SecondsBeforeRespawn <= 0)
107             {
108                 valuesToSend.Add(pi.ViewID);
109                 valuesToSend.Add((
float)0.0f);
110             }
111             
else
112             {
113                 
double timeUntilRespawn = pi.TimeOfRespawn - PhotonNetwork.time;
114                 
if (pi.TimeOfRespawn > soon)
115                 {
116                     
// the respawn of this item is not "immediately", so we include it in the message "these items are not active" for the new player
117                     Debug.Log(pi.ViewID +
" respawn: " + pi.TimeOfRespawn + " timeUntilRespawn: " + timeUntilRespawn + " (now: " + PhotonNetwork.time + ")");
118                     valuesToSend.Add(pi.ViewID);
119                     valuesToSend.Add((
float)timeUntilRespawn);
120                 }
121             }
122         }
123
124         Debug.Log(
"Sent count: " + valuesToSend.Count + " now: " + now);
125         
this.photonView.RPC("PickupItemInit", targtePlayer, PhotonNetwork.time, valuesToSend.ToArray());
126     }
127
128
129     
[RPC]
130     
public void PickupItemInit(double timeBase, float[] inactivePickupsAndTimes)
131     {
132         
this.IsWaitingForPickupInit = false;
133
134         
// if there are no inactive pickups, the sender will send a list of 0 items. this is not a problem...
135         
for (int i = 0; i < inactivePickupsAndTimes.Length / 2; i++)
136         {
137             
int arrayIndex = i*2;
138             
int viewIdOfPickup = (int)inactivePickupsAndTimes[arrayIndex];
139             
float timeUntilRespawnBasedOnTimeBase = inactivePickupsAndTimes[arrayIndex + 1];
140
141
142             PhotonView view = PhotonView.Find(viewIdOfPickup);
143             PickupItem pi = view.GetComponent<PickupItem>();
144
145             
if (timeUntilRespawnBasedOnTimeBase <= 0)
146             {
147                 pi.PickedUp(
0.0f);
148             }
149             
else
150             {
151                 
double timeOfRespawn = timeUntilRespawnBasedOnTimeBase + timeBase;
152
153                 Debug.Log(view.viewID +
" respawn: " + timeOfRespawn + " timeUntilRespawnBasedOnTimeBase:" + timeUntilRespawnBasedOnTimeBase + " SecondsBeforeRespawn: " + pi.SecondsBeforeRespawn);
154                 
double timeBeforeRespawn = timeOfRespawn - PhotonNetwork.time;
155                 
if (timeUntilRespawnBasedOnTimeBase <= 0)
156                 {
157                     timeBeforeRespawn =
0.0f;
158                 }
159
160                 pi.PickedUp((
float) timeBeforeRespawn);
161             }
162         }
163     }
164 }


Finds out which PickupItems are not spawned at the moment and send this to new players.

Attach this component to a single GameObject in the scene, not to all PickupItems.

this client joined the room. let's see if there are players and if someone has to inform us about pickups

find a another player (than the master, who likely is gone) to ask for the PickupItem spawn times

Debug.Log("This player is the Master's next. Asking this client's 'next' player: " + ((nextPlayer != null) ? nextPlayer.ToStringFull() : ""));

you could restart this invoke and try to find another player after 4 seconds. but after a while it doesnt make a difference anymore

this.Invoke("AskForPickupItemSpawnTimes", 2.0f);

Summarizes all PickupItem ids and spawn times for new players. Calls RPC "PickupItemInit".

The player to send the pickup times to. It's a targetted RPC.

the respawn of this item is not "immediately", so we include it in the message "these items are not active" for the new player

if there are no inactive pickups, the sender will send a list of 0 items. this is not a problem...




Trò chơi Tic-Tac-Toe, game đánh caro full source code 53.508 lượt xem

Gõ tìm kiếm nhanh...